import java.util.ArrayList;
import java.util.HashSet;
import java.util.Random;


public class RandomSearchEngine implements SearchEngine {

	private Random generator;
	private Board board;
	private BoardMoveGenerator moveGenerator;
	private HashSet<Piece> triedPieces;
	private boolean giveUp;
	private Node root;
	
	public RandomSearchEngine(Board board) {
		generator = new Random();
		this.board = board;
		moveGenerator = new BoardMoveGenerator(board);
		
		triedPieces = new HashSet<Piece>();
		giveUp = false;
		
		root = new Node();
		root.setBoard(board);
		root.setLevel(0);
	}
	
	@Override
	public void execute(Move[] moves, Piece[] pieces, int playerColor) {
		Piece piece = null;
		ArrayList<BoardMove> possibleMoves = new ArrayList<BoardMove>();
		board.setMovesArray(moves);
		
		int giveUpCounter = 0;
		
		// make sure it's moving a piece from the player's color
		while(piece == null || piece.getColor() != playerColor || possibleMoves.isEmpty()){
			piece = pieces[generator.nextInt(pieces.length-1)];
			
			if(triedPieces.contains(piece)){
				if(piece.getKind() == Piece.TYPE_KING){
					giveUpCounter++;
					if(giveUpCounter == 20){
						giveUp = true;
						break;
					}
				}else continue;
			}
			else triedPieces.add(piece);
		
			// I don't need to generate the possible moves if the piece is not even the player's color
			if(piece.getColor() == playerColor){
				// if the random piece is a pawn, I'll need the last move to test the en passant rule
				possibleMoves = moveGenerator.getPossibleMoves(piece).getAllMoves();
			}else continue;
		}
		
		triedPieces.clear();
		if(!giveUp){			
			randomSearch(piece, possibleMoves, false);
		}else{
			System.out.println("Tried to search for legal moves without success. Will give up.");
		}
	}
	
	// will get a random move from the possibleMoves array a perform it, also by outputting the whole possible moves array
	private void randomSearch(Piece piece, ArrayList<BoardMove> possibleMoves, boolean debug) {
		for (BoardMove move : possibleMoves) {
			MovePerformer movePerformer = new MovePerformer(piece, move);
			Node child = new Node();
			child.setPathParent(root);
			child.setLevel(root.getLevel() + 1);
			child.setUsedMove(movePerformer);
			root.addChild(child);
		}
		
		//BoardMove randomMove = possibleMoves.get(generator.nextInt(possibleMoves.size()));
		Node randomChild = root.getChildren().get(generator.nextInt(root.getChildren().size()));
		BoardMove randomMove = randomChild.getUsedMove().getMove();
		if(debug){
			System.out.print("I'll move my " + piece.getKindString() + " from " + piece.getFile()
					+ "-" + piece.getRank() + " to " + randomMove.toString());
			BoardCell moveTargetCell = new BoardCell(randomMove.getToFile(), randomMove.getToRank());
			Piece targetPiece = board.getPieceOn(moveTargetCell);
			if(targetPiece != null){
				System.out.println(" and capture the other player's " + targetPiece);
			}
			System.out.println();
		}else{
			System.out.println("The " + piece.getKindString() + " could have gone to: " + possibleMoves);
		}
		randomChild.getUsedMove().performMove();
	}

}
